#include "initOpenGL.h"

void init_OpenGL( int &argc , char** argv ) {

    glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize( 800, 600 );
	glutInitWindowPosition( 100, 100 );
	glutCreateWindow("PP2012_Final_Project");

    glEnable(GL_LIGHTING);
    glShadeModel( GL_SMOOTH );
    glEnable( GL_DEPTH_TEST );
    glDepthMask(GL_TRUE);

}

void idle() {

    //option 1
    Euler();  //start simulation using Euler integration
    glutPostRedisplay();

    //option 2
    //RK4();   //start simulation using RK4 integration
    //glutPostRedisplay();

}

void display(){

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    /***** set camera information *****/
    gluLookAt( myCamera.position.x, myCamera.position.y, myCamera.position.z,
               myCamera.view_direction.x , myCamera.view_direction.y , myCamera.view_direction.z,
               myCamera.up_vector.x, myCamera.up_vector.y, myCamera.up_vector.z );
    glRotatef( thetaX , 1 , 0 , 0 );                   // user defined rotation
    glRotatef( thetaY , 0 , 1 , 0 );
    glRotatef( thetaZ , 0 , 0 , 1 );

    GLfloat light0[] = { 0, 200, 200, 1.0 };
    GLfloat lKa0[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat lKd0[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat lKs0[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light1[] = { 200, 200, -200, 1.0 };
    GLfloat lKa1[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat lKd1[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat lKs1[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light2[] = { -200, 200, -200, 1.0 };
    GLfloat lKa2[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat lKd2[] = { 1.0, 1.0, 0.0, 1.0 };
    GLfloat lKs2[] = { 1.0, 1.0, 0.0, 1.0 };
    GLfloat light3[] = { 0.0, -200, 0.0, 1.0 };
    GLfloat lKa3[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat lKd3[] = { 0.0, 1.0, 1.0, 1.0 };
    GLfloat lKs3[] = { 0.0, 1.0, 1.0, 1.0 };

    #define LIGHTSETUP(i)\
    glLightfv(GL_LIGHT##i, GL_POSITION, light##i);\
    glLightfv(GL_LIGHT##i, GL_AMBIENT, lKa##i);\
    glLightfv(GL_LIGHT##i, GL_DIFFUSE, lKd##i);\
    glLightfv(GL_LIGHT##i, GL_SPECULAR, lKs##i);\
    glEnable(GL_LIGHT##i);

    LIGHTSETUP(0)
    LIGHTSETUP(1)
    //LIGHTSETUP(2)
   // LIGHTSETUP(3)

    /***** draw scene *****/
    //draw box
    glColor4d( 0.2 , 0.2 , 0.2 , 0.2);
    glBegin( GL_QUADS );
        glVertex3d( -myBox.size ,  myBox.size ,  myBox.size ); // face left
        glVertex3d( -myBox.size , -myBox.size ,  myBox.size );
        glVertex3d( -myBox.size , -myBox.size , -myBox.size );
        glVertex3d( -myBox.size ,  myBox.size , -myBox.size );
        /*glVertex3d(  myBox.size ,  myBox.size ,  myBox.size ); // face right
        glVertex3d(  myBox.size , -myBox.size ,  myBox.size );
        glVertex3d(  myBox.size , -myBox.size , -myBox.size );
        glVertex3d(  myBox.size ,  myBox.size , -myBox.size );
        glVertex3d( -myBox.size ,  myBox.size ,  myBox.size ); // face up
        glVertex3d(  myBox.size ,  myBox.size ,  myBox.size );
        glVertex3d(  myBox.size ,  myBox.size , -myBox.size );
        glVertex3d( -myBox.size ,  myBox.size , -myBox.size );*/
        glVertex3d( -myBox.size , -myBox.size ,  myBox.size ); // face down
        glVertex3d(  myBox.size , -myBox.size ,  myBox.size );
        glVertex3d(  myBox.size , -myBox.size , -myBox.size );
        glVertex3d( -myBox.size , -myBox.size , -myBox.size );
        /*glVertex3d( -myBox.size ,  myBox.size ,  myBox.size ); // face front
        glVertex3d( -myBox.size , -myBox.size ,  myBox.size );
        glVertex3d(  myBox.size , -myBox.size ,  myBox.size );
        glVertex3d(  myBox.size ,  myBox.size ,  myBox.size );*/
        glVertex3d( -myBox.size ,  myBox.size , -myBox.size ); // face back
        glVertex3d( -myBox.size , -myBox.size , -myBox.size );
        glVertex3d(  myBox.size , -myBox.size , -myBox.size );
        glVertex3d(  myBox.size ,  myBox.size , -myBox.size );
    glEnd();

    //draw particles
    glColor4d( 0.7 , 0.0 , 0.3 , 1.0 );
    int i;
    for( i=0; i<myParticles.number; i++ ) {
        glPushMatrix();
        glTranslated( myParticles.position[i].x , myParticles.position[i].y , myParticles.position[i].z );
        glutSolidSphere( myParticles.radius[i] , 100,100);
        glPopMatrix();
    }

	glutSwapBuffers();

}

void reshape(int w, int h) {
    glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if(h<100)h=101;
	if(w<100)w=101;
	double ratio=1.0*(w-100)/(h-100);
	gluPerspective(90,ratio,1,100000);
}

void keyboard(unsigned char key, int x, int y){
	switch(key){
	    //exit
		case 27:
			exit(0);
        case 'w':
            thetaY += 10%360;
			glutPostRedisplay();
			break;
		case 's':
            thetaY -= 10%360;
			glutPostRedisplay();
			break;
		case 'a':
            thetaX -= 10%360;
			glutPostRedisplay();
			break;
        case 'd':
            thetaX += 10%360;
			glutPostRedisplay();
			break;
		case 'q':
            thetaZ -= 10%360;
			glutPostRedisplay();
			break;
		case 'e':
            thetaZ += 10%360;
			glutPostRedisplay();
			break;
    }
}
